﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Drawing.Imaging;
using System.IO;
using System.Xml;
using System.Drawing;

namespace blackhouse.Web {
    /// <summary>
    /// Summary description for DynamicImageFileBased1
    /// </summary>
    public class DynamicImageFileBased : DynamicImage {

        #region Fields

        private bool configurationIsReaded = false;
        private string pathToFiles = "";
        private string matrix = "";
        private ColorMatrix cm;

        #endregion

        #region DynamicImage Members

        protected override string GetGuid(string fileName) {
            FileInfo fi = this.GetFileInfo(fileName);
            if (fi.Exists) {
                this.lastModified = fi.LastWriteTimeUtc;
                return (fi.Name + fi.LastWriteTimeUtc);
            }
            else
                return "";
        }

        protected override System.IO.Stream ReadImageStream(string fileNameWithExtension) {
            FileInfo fi = this.GetFileInfo(fileNameWithExtension);
            if (fi.Exists)
                return fi.OpenRead();
            else
                return null;
        }

        protected override System.Drawing.Imaging.ColorMatrix GetModification() {
            return this.cm;
        }

        protected override string GetFileNameWithExtension(Uri url) {
            this.SetConfiguration();
            return pathToFiles + HttpContext.Current.Request["file"].ReplaceEx(",", "/");
        }

        protected override System.Drawing.Size GetBoxSize(Uri url) {
            int width, height;
            if (
                Int32.TryParse(HttpContext.Current.Request["width"], out width)
                && Int32.TryParse(HttpContext.Current.Request["height"], out height))
                return new System.Drawing.Size(width, height);
            else
                return System.Drawing.Size.Empty;
        }

        #endregion

        #region Methods

        private FileInfo GetFileInfo(string fileName) {
            FileInfo fi = new FileInfo(HttpContext.Current.Server.MapPath(fileName));
            return fi;
        }

        private void SetConfiguration() {
            if (this.configurationIsReaded)
                return;

            FileInfo file = new FileInfo(HttpContext.Current.Server.MapPath("/" + HttpContext.Current.Request["configuration"] + ".image.config"));
            if (file.Exists) {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(file.FullName);
                XmlNode xmlPathToFiles = xmlDoc.SelectSingleNode("/Config/PathToFiles");
                if (xmlPathToFiles != null) this.pathToFiles = xmlPathToFiles.InnerText;
                XmlNode xmlMatrix = xmlDoc.SelectSingleNode("/Config/MatrixModification");
                if (xmlMatrix != null) this.matrix = xmlMatrix.FirstChild.InnerText;

                this.EndSetConfiguration();
            }
        }

        private void EndSetConfiguration() {
            if (!this.pathToFiles.EndsWith("/")) this.pathToFiles = this.pathToFiles + "/";
            try {

                if (!string.IsNullOrEmpty(this.matrix)) {
                    string[] matrixLines = this.matrix.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
                    float[][] matrixValues = new float[5][];
                    int crnRow = 0;
                    foreach (string matrixLine in matrixLines) {
                        if (string.IsNullOrEmpty(matrixLine) || crnRow > 4)
                            continue;
                        string[] matrixLineItems = matrixLine.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                        if (matrixLineItems.Length != 5)
                            continue;

                        float[] rowItems = new float[5];
                        for (int xi = 0; xi < 5; xi++) {
                            rowItems[xi] = Convert.ToSingle(matrixLineItems[xi], System.Globalization.CultureInfo.InvariantCulture);
                        }
                        matrixValues[crnRow] = rowItems;
                        crnRow++;
                    }
                    this.cm = new ColorMatrix(matrixValues);
                }
            } catch (Exception) {
                this.matrix = "";
            }

            this.configurationIsReaded = true;
        }

        #endregion

    }
}